<template>
  <el-form ref="form" :model="value" :label-width="lw">
    <el-form-item
      v-for="(item, key) in options"
      :key="key"
      :rules="item.rules"
      :prop="key"
      :label="showLabel ? item.title : undefined"
    >
      <el-input
        v-if="item.tag === 'input'"
        v-model="value[key]"
        :disabled="item.dis"
        :placeholder="item.ph"
        :maxlength="item.max"
        :type="item.type"
      ></el-input>
    </el-form-item>
  </el-form>
</template>

<script>
import { deepClone } from "uti/common";

/**
 * 判断是否是数字
 */
const isNumber = (val) => typeof val === "number";
export default {
  name: "MyForm",
  mounted() {
    const { validate, clearValidate } = this.$refs.form;
    Object.assign(this, { validate, clearValidate });
  },
  computed: {
    /**
     * 表单配置
     */
    options() {
      const options = deepClone(this.opts);
      for (const key in options) {
        const item = options[key];
        item.tag = item.tag || "input";
        item.type = item.type || "text";
        item.rules = item.rules || [];

        // 如果有required字段，给rules添加required规则
        if (item.required) {
          item.rules.unshift({ required: true });
        }

        // 生成message
        for (const rule of item.rules) {
          if (isNumber(item.max) && isNumber(rule.min)) {
            rule.max = item.max;
          }
          if (rule.message) {
            continue;
          }

          if (isNumber(rule.min) && isNumber(rule.min)) {
            rule.message = `${item.title}长度为${rule.min}到${rule.max}位`;
          } else if (isNumber(rule.min)) {
            rule.message = `${item.title}最小长度为${rule.min}`;
          } else if (isNumber(rule.min)) {
            rule.message = `${item.title}最大长度为${rule.max}`;
          } else if (item.required) {
            rule.message = `${item.title}不能为空`;
          }
        }
      }
      return options;
    },
  },
  props: {
    /**
     * 是否显示label
     */
    showLabel: {
      type: Boolean,
      default: true,
    },
    /**
     * label宽度
     */
    lw: {
      type: String,
      default: "auto",
    },
    /**
     * 表单参数
     */
    opts: {
      type: Object,
      required: true,
      default: () => {},
    },
    /**
     * 表单值
     */
    value: {
      required: true,
      type: Object,
      default: () => {},
    },
  },
};
</script>

<style>
</style>